home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Taifun / Taifun 175 (1991-09-10)(Manewaldt, A.)(DE)(PD).zip / Taifun 175 (1991-09-10)(Manewaldt, A.)(DE)(PD).adf / Term / Source.LZH / Res.asm < prev    next >
Assembly Source File  |  1991-07-26  |  7KB  |  139 lines

  1. *:ts=8
  2. *****************************************************************************
  3. *                                                                           *
  4. * RES.S                                    (C) Copyright Eddy Carroll 1989  *
  5. *                                                                           *
  6. * This module allows you to make a duplicate copy of your current process.  *
  7. * In fact, both processes actually share the same code. However, the        *
  8. * seglist pointer of the current process is modified so that when the       *
  9. * process terminates, the memory doesn't get freed (if it did, the new      *
  10. * process would suddenly find itself deallocated. Hello guru...)            *
  11. * This code only works when called from CLI processes.                      *
  12. *                                                                           *
  13. * The parameters passed are similar to those for CreateProc(), with the     *
  14. * difference that instead of passing a BPTR to a seglist, you pass the      *
  15. * address of the function the new process should start executing at.        *
  16. *                                                                           *
  17. * When the new process returns from this function, it will be removed from  *
  18. * the system, and its memory (finally) deallocated.                         *
  19. *                                                                           *
  20. * The typical use for a function like this is to allow a program to detach  *
  21. * itself from a CLI (completely, with no trailing console handles etc.)     *
  22. * when it is run. This is a convenient feature for the user, if the program *
  23. * is of the sort designed to sit in the background the whole time, rather   *
  24. * than do something immediately, then exit.                                 *
  25. *                                                                           *
  26. * Lattice provide cback.o which at first glance would seem to provide a     *
  27. * similar solution. However, cback.o makes it difficult to print error      *
  28. * messages to the console if there is an error on the command line - by     *
  29. * the time you spot the error, the CLI prompt has already been printed      *
  30. * and your error message is printed after it. This looks very messy.        *
  31. * Res avoids this problem by not spawning the background process until      *
  32. * after the error checking has been done.                                   *
  33. *                                                                           *
  34. * From C, you call it as follows:                                           *
  35. *                                                                           *
  36. * pid = res(name,pri,func,stacksize)                                        *
  37. *                                                                           *
  38. * name         - pointer to null terminated string                          *
  39. * pri          - integer, priority of the new process                       *
  40. * func         - pointer to the function for new process to call            *
  41. * stacksize    - integer, size of the stack for the new process             *
  42. *                                                                           *
  43. * pid          - Process ID of new process, or 0 if none created            *
  44. *                                                                           *
  45. *                                                                           *
  46. * Minor changes introduced by Olaf `Olsen' Barthel, mostly concerning       *
  47. * clearing of the code and data caches before actually creating the         *
  48. * new process (this was necessary for '040 compatibility's sake).           *
  49. *                                                                           *
  50. *****************************************************************************
  51.  
  52.     INCLUDE "exec/types.i"
  53.     INCLUDE    "exec/execbase.i"
  54.         INCLUDE "libraries/dosextens.i"
  55.  
  56.     xref    _DOSBase
  57.     xdef    _Res
  58.  
  59. AbsExecBase    equ    4
  60. segsize        equ    36        ; Size of fake seg. (code = 28 bytes)
  61.  
  62.         csect   text,0,0,1,2        * xref's after this are 16-bit reloc
  63.  
  64. callsys macro
  65.     xref    _LVO\1
  66.     jsr    _LVO\1(a6)
  67.     endm
  68.  
  69. _Res:
  70.     movem.l    d2-d4/a2/a3/a6,-(a7)    ; Save registers
  71.     move.l    AbsExecBase.w,a6    ; Get base of Exec library
  72.     moveq    #0,d1            ; Any sort of memory will do
  73.     moveq    #segsize,d0        ; Get size of fake segment
  74.     callsys    AllocMem        ; Grab some memory
  75.     tst.l    d0            ; Did we get any?
  76.     beq    fatal            ; If not, abort immediately!
  77.     move.l    d0,a3            ; Save pointer to memory
  78.     sub.l    a1,a1            ; NULL pointer indicates our process
  79.     callsys    FindTask        ; Get pointer to our process block
  80.     move.l    d0,a2            ; Save it
  81.     move.l    pr_CLI(A2),a0        ; Get BPTR to our process's segarray
  82.     add.l    a0,a0            ; Convert BPTR to address
  83.     add.l    a0,a0            ; 
  84.     move.l    cli_Module(a0),4(a3)    ; Make fake segment point to our code
  85.     clr.l    cli_Module(a0)        ; Remove process seg. from CLI seglist
  86.     move.l    #segsize,(a3)        ; Set size of fake seglist
  87.     lea.l    8(a3),a2        ; Get pointer to first code byte
  88.  
  89. ;
  90. ; Now a tiny machine code program is constructed. It looks like this:
  91. ;
  92. ;    move.l    #$xxxxxx,A4    ; Initialise A4
  93. ;    jsr    $xxxxxx        ; Call user program
  94. ;    move.l    #$xxxxxx,A6    ; Load DOSbase into A6
  95. ;    move.l    #$xxxxxx,d1    ; Get BPTR to this segment 
  96. ;    jmp    UnLoadSeg(A6)    ; Unload our process from memory
  97. ;
  98. ; It's built "on the fly" so to speak, to keep code size down, and also
  99. ; because it's a convenient way of initialising all the variables.
  100. ; Note that a potential problem exists if DOSBase should somehow alter or
  101. ; disappear. We'll assume it will remain relatively stable for the next
  102. ; few years anyway :-)
  103. ;
  104.  
  105.     move.l    _DOSBase,a6
  106.     move.w    #$287C,(a2)+        ; Store MOVE.L $xxxxxx,A4 instruction
  107.     move.l    a4,(a2)+        ; Output value of A4 to initialise to
  108.     move.w    #$4EB9,(a2)+        ; Store JSR $xxxxxx
  109.     move.l    36(a7),(a2)+        ; followed by address of user function
  110.     move.w    #$2C7C,(a2)+        ; Store MOVE.L $xxxxxx,A6 instruction
  111.     move.l    a6,(a2)+        ; followeds by current DOSbase
  112. ;
  113.     lea    4(a3),a3        ; Now get seglist ptr to fake segment
  114.     move.l    a3,d3            ; and convert it to BPTR
  115.     lsr.l    #2,d3            ; D3 now has seglist ptr to fake seg
  116.     move.w    #$223C,(a2)+        ; Store MOVE.L $xxxxxx,D1 instruction
  117.     move.l    d3,(a2)+        ; Followed by BPTR to the segment
  118.     move.l    #$4EEEFF64,(a2)+    ; Store JMP UnLoadSeg(A6)
  119. ;
  120.     move.l    AbsExecBase.w,a6    ; Get back ExecBase
  121.     cmpi.w    #37,LIB_VERSION(a6)    ; Skip if library call not available
  122.     bcs.s    old
  123.     btst    #AFB_68030,AttnFlags(a6) ;Skip if no cache available
  124.     beq.s    old
  125.     callsys    CacheClearU        ; Clear the user cache
  126.  
  127. old:    move.l    _DOSBase,a6        ; Prepare for DOS call
  128.     move.l    28(A7),d1        ; Get pointer to name
  129.     move.l    32(A7),d2        ; Get process priority
  130.     move.l    40(A7),d4        ; Get stacksize
  131.     callsys    CreateProc        ; Create new process
  132.     movem.l    (a7)+,d2-d4/a2/a3/a6    ; Pop registers
  133.     rts                ; Return
  134. fatal:
  135.     moveq    #0,d0            ; Set error exit code
  136.     rts                ; And exit
  137.  
  138.     end
  139.